﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Microsoft.Extensions.DependencyInjection;

using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using IContainer = Autofac.IContainer;
using SSRSCore.Scrum.Core;
using SSRS.Util;

namespace SSRS.Autofac
{
    public class SrAutofacCore
    {
       
        public static void AutoFac(ContainerBuilder builder)
        {

            //Assembly coreAssembly = Assembly.Load("SSRS.Autofac");
            ////帮助类自动注入
            //builder.RegisterAssemblyTypes(coreAssembly)
            //    .Where(t => t.Name.EndsWith("Helper")).PropertiesAutowired();
            ////代码生成器注入
            //Assembly ssrcodeGenerator = Assembly.Load("SSRS.Core.CodeGenerator"); 
            //builder.RegisterAssemblyTypes(ssrcodeGenerator)
            //    .Where(t => t.Name.EndsWith("CodeGenerator")).PropertiesAutowired();
            ////WebApi自动注入
         
           

            #region 系统框架扩展属性装配

            Type myType = typeof(SrAutofacCore);
            string currentDirectory = Path.GetDirectoryName(myType.Assembly.Location);

            string[] alliocdll = Directory.GetFiles(currentDirectory, "SSRSCore.Scrum.*.dll");
            
            if (alliocdll.Length>0)
            {
                Assembly[] icoAssemblies = new Assembly[alliocdll.Length];
                for (int i = 0; i < icoAssemblies.Length; i++)
                {
                    FileInfo fi = new FileInfo(alliocdll[i]);

                    
                    icoAssemblies[i] = Assembly.Load(fi.Name.Substring(0, fi.Name.LastIndexOf('.')));
                }
                builder.RegisterAssemblyTypes(icoAssemblies)
                    .Where(t => t.Name.EndsWith("BLL"))
                    .AsImplementedInterfaces().PropertiesAutowired();
                builder.RegisterAssemblyTypes(icoAssemblies)
                    .Where(t => t.Name.EndsWith("Service")).PropertiesAutowired();

                    
            }
            #endregion


        }

        public static IContainer RegisterAutofac(IServiceCollection services)
        {
            var builder = new ContainerBuilder();
            var manager = new ApplicationPartManager();
            Type myType = typeof(SrAutofacCore);
            string currentDirectory = Path.GetDirectoryName(myType.Assembly.Location);

            List<string> alliocdll = Directory.GetFiles(currentDirectory, "SSRSCore.Scrum.*.dll").ToList<string>();

            alliocdll= alliocdll.Where(p => !p.EndsWith("Views.dll")).ToList();
            if (alliocdll.Count > 0)
            {
                List<Assembly> icoAssemblies = new List<Assembly>();
                for (int i = 0; i < alliocdll.Count; i++)
                {
                  
                    FileInfo fi = new FileInfo(alliocdll[i]);
                    string assemblyName = fi.Name.Substring(0, fi.Name.LastIndexOf('.'));
                    Console.WriteLine(assemblyName);
                    Assembly singAssembly = null;
                    try
                    {
                        singAssembly = Assembly.Load(assemblyName);
                        icoAssemblies.Add(singAssembly);
                        
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        continue;
                        

                    }

                    if (singAssembly!=null)
                    {
                        manager.ApplicationParts.Add(new AssemblyPart(singAssembly));
                    }
                   
                }

                manager.FeatureProviders.Add(new ControllerFeatureProvider());


                var feature = new ControllerFeature();
                
                manager.PopulateFeature(feature);

                builder.RegisterType<ApplicationPartManager>().AsSelf().SingleInstance();
                builder.RegisterTypes(feature.Controllers.Select(ti => ti.AsType()).ToArray()).PropertiesAutowired();
                 
                builder.Populate(services);



                builder.RegisterType<AopInterceptor>();


                builder.RegisterAssemblyTypes(icoAssemblies.ToArray())
                    .Where(type =>
                        typeof(IDependency).IsAssignableFrom(type) && !type.GetTypeInfo().IsAbstract)
                    .AsImplementedInterfaces()
                    .InstancePerLifetimeScope()
                    .EnableInterfaceInterceptors().InterceptedBy(typeof(AopInterceptor));
                builder.RegisterType<SrAutofacCore>().PropertiesAutowired();
                SrAutofacCore.AutoFac(builder);
            }


            #region 特殊的注入
            builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>();
            
            #endregion
            return builder.Build();


        }

    }
}
